package com.bestcem.xm.qdes.handler.export.type;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bestcem.xm.qdes.enums.QuestionTypeEnum;
import com.bestcem.xm.qdes.handler.export.BaseTypeHandler;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

@Component
public class ProportionHandler implements BaseTypeHandler {

    @Override
    public List<Object> getItems(JSONObject questionDict, JSONObject qgidDict, List<JSONObject> relatedRefs) {
        // 比重题
        List<Object> items = new ArrayList<>();

        String qcid = questionDict.getString("cid");
        String qtitle = questionDict.getString("title");
        String qtype = questionDict.getString("qtype");

        int dispSelect = (int) questionDict.getOrDefault("dispSelect", 0);  // dispSelect:0 选项设置; 1 代码设置
        boolean codeSelect = (boolean) questionDict.getOrDefault("codeSelect", true); // true: 显示代码/false: 抹灰代码
        int jumpSelect = (int) questionDict.getOrDefault("jumpSelect", 0);  // jumpSelect:0 选项设置; 1 代码设

        String dispCode = (String) questionDict.getOrDefault("disp_code", "");  // 显示代码
        String jumpCode = (String) questionDict.getOrDefault("jump_code", "");  // 跳转代码
        String autoCode = (String) questionDict.getOrDefault("auto_code", "");  // 自动勾选代码

        boolean required = questionDict.getBoolean("required");  // 必答
        String total = questionDict.getString("total");  // 比重总和

        List<Integer> optionsRange = castList(questionDict.getOrDefault("options_range", new ArrayList<>(Arrays.asList(0, 0))), Integer.class);
        String typeStr = QuestionTypeEnum.valueOf("QUESTION_TYPE_" + qtype.toUpperCase()).getDesc();

        List<String> item0 = new ArrayList<>();
        item0.add(qcid + "[" + typeStr + "]");
        item0.add(qtitle);

        List<String> qAttr = new ArrayList<>();
        qAttr.add(required ? "必答" : "非必答");
        qAttr.add(String.format("比重总和#%s", total));

        if (optionsRange.get(0) != 0) {
            qAttr.add(String.format("最少选%s项", optionsRange.get(0)));
        }
        if (optionsRange.get(1) != 0) {
            qAttr.add(String.format("最多选%s项", optionsRange.get(1)));
        }

        if (dispSelect == 1 && codeSelect) {
            qAttr.add("显示代码");
        } else if (dispSelect == 1 && !codeSelect) {
            qAttr.add("抹灰代码");
        } else {
            qAttr.add("");
        }

        // 题目属性
        List<String> allAttr = new ArrayList<>();
        qAttr.forEach(at -> {
            allAttr.add("[" + at + "]");
        });
        item0.add(String.join("", allAttr));
        // 显示代码，跳转代码，自动勾选代码
        item0.add(dispSelect == 1 ? dispCode : "");
        item0.add(jumpSelect == 1 ? jumpCode : "");
        item0.add(autoCode);
        items.add(item0);

        // 处理选项
        String optionsRandom = questionDict.getString("options_random"); // 选项顺序: True, "sort", "reverse"

        JSONArray optionItems = Optional.ofNullable(questionDict.getJSONArray("items")).orElse(new JSONArray());
        if (!optionItems.isEmpty() || CollectionUtils.isNotEmpty(relatedRefs)) {
            List<String> optionCommAttr = new ArrayList<>();  // 选项属性
            optionCommAttr.add("顺序#" + ("True".equals(optionsRandom) ? "随机" : ("sort".equals(optionsRandom) ? "循环"
                    : ("reverse".equals(optionsRandom) ? "倒序" : "默认"))));

            // 处理选项关联
            if (CollectionUtils.isNotEmpty(relatedRefs)) {
                List<String> relatedTmps = new ArrayList<>();
                for (JSONObject related : relatedRefs) {
                    String sourceGid = related.getString("sourceGid");
                    String mode = related.getString("mode");
                    JSONObject question = qgidDict.getJSONObject(sourceGid);

                    List<String> tmps = new ArrayList<>();
                    tmps.add("关联");
                    tmps.add(question.getString("cid"));
                    tmps.add("unselect".equals(mode) ? "未选中项" : "选中项");
                    relatedTmps.add(String.join("#", tmps));
                }
                optionCommAttr.addAll(relatedTmps);
            }
            List<String> tmpList = new ArrayList<>();
            tmpList.add("选项");
            tmpList.add("");
            List<String> comAttr = new ArrayList<>();
            optionCommAttr.forEach(at -> {
                comAttr.add("[" + at + "]");
            });
            tmpList.add(String.join("", comAttr));
            items.add(tmpList);

            for (Object oneItem : optionItems) {
                JSONObject optionDict = (JSONObject) oneItem;
                List<String> optionAttr = new ArrayList<>();

                boolean isOpen = optionDict.getBoolean("is_open");

                String dispCode1 = (String) optionDict.getOrDefault("disp_code", "");  // 显示代码
                String plasterCode1 = (String) optionDict.getOrDefault("plaster_code", "");  // 抹灰代码
                autoCode = (String) optionDict.getOrDefault("auto_code", "");  // 自动勾选代码
                boolean forbidRelated = (Boolean) optionDict.getOrDefault("forbidRelated", false); // 禁止选项关联

                boolean fixed = (Boolean) optionDict.getOrDefault("fixed", false); // 选项固定

                if (forbidRelated) {
                    optionAttr.add("禁止选项关联");
                }
                if (fixed) {
                    optionAttr.add("固定");
                }
                if (isOpen) {
                    JSONObject openAttrs = (JSONObject) optionDict.getOrDefault("open_attrs", new JSONObject());
                    List<String> optionOpenAttrs = optionOpenParse(openAttrs);
                    optionAttr.add(String.join("#", optionOpenAttrs));
                }

                List<String> opAttr = new ArrayList<>();
                optionAttr.forEach(at -> {
                    opAttr.add("[" + at + "]");
                });
                String optionAttrstr = String.join("", opAttr);

                List<String> tList = new ArrayList<>();
                tList.add(optionDict.getString("oid"));
                tList.add(optionDict.getString("title"));
                tList.add(optionAttrstr);
                if (dispSelect == 1 && codeSelect) {
                    tList.add(dispCode1);
                } else if (dispSelect == 1 && !codeSelect) {
                    tList.add(plasterCode1);
                } else {
                    tList.add("");
                }
                tList.add("");
                tList.add(autoCode);
                items.add(tList);
            }
        }

        return items;
    }

    @Override
    public String getType() {
        return "proportion";
    }
}
